package com.my.core.util;

import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.Enumeration;

public class INetUtil
{
    public static final String LOCAL_HOST = "127.0.0.1";

    /**
     * 获取客户端ip地址
     * @return
     */
    public static String getAddressIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String getHostName() {
        String hostname;
        try {
            final InetAddress address = InetAddress.getLocalHost();
            hostname = address.getHostName();
            if (StringUtils.isEmpty((Object)hostname)) {
                hostname = address.toString();
            }
        }
        catch (UnknownHostException ignore) {
            hostname = "127.0.0.1";
        }
        return hostname;
    }

    public static String getHostIp() {
        String hostAddress;
        try {
            final InetAddress address = getLocalHostLANAddress();
            hostAddress = address.getHostAddress();
            if (StringUtils.isEmpty((Object)hostAddress)) {
                hostAddress = address.toString();
            }
        }
        catch (UnknownHostException ignore) {
            hostAddress = "127.0.0.1";
        }
        return hostAddress;
    }

    private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
        try {
            InetAddress candidateAddress = null;
            final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
            while (ifaces.hasMoreElements()) {
                final NetworkInterface iface = ifaces.nextElement();
                final Enumeration<InetAddress> inetAddrs = iface.getInetAddresses();
                while (inetAddrs.hasMoreElements()) {
                    final InetAddress inetAddr = inetAddrs.nextElement();
                    if (!inetAddr.isLoopbackAddress()) {
                        if (inetAddr.isSiteLocalAddress()) {
                            return inetAddr;
                        }
                        if (candidateAddress != null) {
                            continue;
                        }
                        candidateAddress = inetAddr;
                    }
                }
            }
            if (candidateAddress != null) {
                return candidateAddress;
            }
            final InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            if (jdkSuppliedAddress == null) {
                throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
            }
            return jdkSuppliedAddress;
        }
        catch (Exception e) {
            final UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
            unknownHostException.initCause(e);
            throw unknownHostException;
        }
    }

    public static boolean tryPort(final int port) {
        try (final ServerSocket ignore = new ServerSocket(port)) {
            return true;
        }
        catch (Exception e) {
            return false;
        }
    }
}
